<template>
  <div class="yy-widget-dialog">
    <el-drawer :close-on-click-modal="option?.closeOnClickModal" class="yy-modal--custom" :size="option.size" v-model="isVisible" @close="onCancelModel" :show-close="true">
      <template #header="{ close, titleId, titleClass }">
        <h4 :id="titleId" :class="titleClass">
          <span v-if="option.title">{{option.title}}</span>
          <span v-else>{{originData?.id ? '编辑':'新建'}}{{option.businessName}}</span>
        </h4>
        <el-icon class="pc-modal--custom_close el-icon--left" @click="close" style="cursor: pointer"><IconClose /></el-icon>
      </template>
      <div class="yy-widget-dialog_content">
        <WidgetForm ref="formDialogRef" :form-fields="formFields" :option="option"></WidgetForm>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="onCancelModel">关闭</el-button>
          <el-button type="primary" :loading="isLoading" @click="onSave">保存</el-button>
        </span>
      </template>
    </el-drawer>
  </div>
</template>
<script setup lang="ts">
import {defineEmits, defineExpose, defineProps, nextTick, ref} from 'vue'
import {ElMessage} from "element-plus";
import {BaseModel} from "@/model/BaseModel";

const formDialogRef = ref()

const props = defineProps({
  option: {
    type: Object,
    required: false,
    default: null
  },
  formFields: {
    type: Array,
    required: true,
    default: () => []
  },
  modelInstance: {
    type: BaseModel,
    required: true,
    default: () => null
  },
  saveApiFun: {
    type: Function,
    required: true,
    default: () => null
  },
  updateApiFun: {
    type: Function,
    required: true,
    default: () => null
  }
})

const isVisible = ref(false)
const isLoading = ref(false)
const originData = ref<Record<string, any>>()

const $emit = defineEmits({
  editCallback: ((data: BaseModel) => data),
})

const onShowModel = (data: Record<string, any>) => {
  isVisible.value = true
  if (data) {
    originData.value = data
    nextTick(() => {
      formDialogRef.value.initFormData(data)
    })
  }
}

const onCancelModel = () => {
  originData.value = null
  if (isVisible.value) {
    setTimeout(() => {
      formDialogRef.value.resetFields()
    }, 200)
  }
  isVisible.value = false
}

const getFormFieldValue = () => {
  let modelProperty = {
    id: originData.value ? originData.value.id : undefined
  }
  const formFieldProperty = formDialogRef.value.getFormFieldValue()
  modelProperty = Object.assign({}, modelProperty, formFieldProperty)
  return modelProperty;
}

const onSave = () => {
  formDialogRef.value.validateForm((valid, fields) => {
    if (valid) {
      let modelProperty = {
        id: originData.value ? originData.value.id : undefined
      }
      const formFieldProperty = formDialogRef.value.getFormFieldValue()
      modelProperty = Object.assign({}, modelProperty, formFieldProperty)

      const modelData = props.modelInstance.deserialize(modelProperty)

      isLoading.value = true
      if (originData.value?.id) {
         props.updateApiFun(originData.value.id, modelData).then(() => {
           originData.value.deserialize(Object.assign({}, modelProperty, {
             updateTime: new Date()
           }))
           ElMessage.success({
             message: '记录更新成功',
             showClose: true
           })
           $emit('editCallback', originData.value)
           isLoading.value = false
           onCancelModel()
         }, () => {
           isLoading.value = false
         })
      } else {
        props.saveApiFun(modelData).then((res) => {
          ElMessage.success({
            message: '记录新建成功',
            showClose: true
          })
          $emit('editCallback', res)
          isLoading.value = false
          onCancelModel()
        }, () => {
          isLoading.value = false
        })
      }
    }
  })
}

const setFieldValue = (field: string, val: any) => {
 formDialogRef.value.setFieldValue(field, val)
}

defineExpose({
  onShowModel,
  setFieldValue,
  getFormFieldValue
})
</script>
<style scoped lang="scss">
.yy-widget-dialog {
  ::v-deep(.el-dialog__body) {
    max-height: 500px;
    overflow-y: auto;
  }
  &_content {
    padding: 20px;
  }
  .dialog-footer {
    display: flex;
    & > button {
      flex: 1;
    }
  }
}
</style>